package com.hongyi.modelcontest.modular.system.service;

import cn.stylefeng.roses.core.util.ToolUtil;
import cn.stylefeng.roses.kernel.model.exception.ServiceException;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.hongyi.modelcontest.core.common.exception.BizExceptionEnum;
import com.hongyi.modelcontest.core.common.node.TreeviewNode;
import com.hongyi.modelcontest.core.common.node.ZTreeNode;
import com.hongyi.modelcontest.core.common.page.LayuiPageFactory;
import com.hongyi.modelcontest.core.shiro.ShiroKit;
import com.hongyi.modelcontest.core.shiro.ShiroUser;
import com.hongyi.modelcontest.core.util.Base64Util;
import com.hongyi.modelcontest.core.util.SpringbootUtils;
import com.hongyi.modelcontest.modular.contest.entity.ContestInfo;
import com.hongyi.modelcontest.modular.contest.mapper.ContestInfoMapper;
import com.hongyi.modelcontest.modular.system.entity.Dept;
import com.hongyi.modelcontest.modular.system.entity.User;
import com.hongyi.modelcontest.modular.system.mapper.DeptMapper;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils;
import org.springframework.util.StringUtils;

import javax.annotation.Resource;
import java.util.ArrayList;
import java.util.Comparator;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

/**
 * <p>
 * 城市合伙人表 服务实现类
 * </p>
 *
 * @author stylefeng
 * @since 2018-12-07
 */
@Service
public class DeptService extends ServiceImpl<DeptMapper, Dept> {

    @Resource
    private DeptMapper deptMapper;
    @Resource
    private UserService userService;
    @Resource
    private ContestInfoMapper contestInfoMapper;

    public String createUrl(String deptId, String route) {
        ContestInfo contestInfo = contestInfoMapper.selectOne(new QueryWrapper<ContestInfo>().lambda()
                .orderByDesc(ContestInfo::getCreatedTime).last(" limit 1"));
        if (contestInfo != null && contestInfo.getRegistEndTime().getTime() > System.currentTimeMillis()) {
            String state = "";
            if (!StringUtils.isEmpty(deptId)) {
                state += "&D=" + deptId;
            }
            //&A=1106098065745379330&C=20190312201108&D=1105445531393572866&R=welcomepage
            state += "&C=" + contestInfo.getContestId() + "&R=" + route;
            return SpringbootUtils.getRemotUrl() + "/contest/wx?state=" + Base64Util.encode(state);
        } else {
            throw new ServiceException(500, "活动已结束！");
        }
    }

    /**
     * 新增城市合伙人
     *
     * @author fengshuonan
     * @date 2018/12/23 5:00 PM
     */
    @Transactional(rollbackFor = Exception.class)
    public void addDept(Dept dept) {

        if (ToolUtil.isOneEmpty(dept, dept.getPName(), dept.getPid())) {
            throw new ServiceException(BizExceptionEnum.REQUEST_NULL);
        }
        //完善pids,根据pid拿到pid的pids
        this.deptSetPids(dept);

        this.save(dept);
    }

    /**
     * 修改城市合伙人
     *
     * @author fengshuonan
     * @Date 2018/12/23 5:00 PM
     */
    @Transactional(rollbackFor = Exception.class)
    public void editDept(Dept dept) {

        if (ToolUtil.isOneEmpty(dept, dept.getPName(), dept.getPid())) {
            throw new ServiceException(BizExceptionEnum.REQUEST_NULL);
        }
        Dept pd = this.getById(dept.getPid());

        //完善pids,根据pid拿到pid的pids
        this.deptSetPids(dept);
        if (ToolUtil.isEmpty(dept.getSimpleName())) {
            dept.setSimpleName(pd.getSimpleName());
        }
        if (ToolUtil.isEmpty(dept.getLogo())) {
            dept.setLogo(null);
        }
        if (ToolUtil.isEmpty(dept.getAssist())) {
            dept.setAssist(null);
        }
        if (ToolUtil.isEmpty(dept.getQrCode())) {
            dept.setQrCode(null);
        }
        this.updateById(dept);
    }

    /**
     * 删除城市合伙人
     *
     * @author fengshuonan
     * @Date 2018/12/23 5:16 PM
     */
    @Transactional
    public void deleteDept(Long deptId) {
        List<User> list = userService.list(new QueryWrapper<User>().lambda()
                .eq(User::getDeptId, deptId));
        if (!CollectionUtils.isEmpty(list)) {
            throw new ServiceException(500, " 请先删除城市合伙人下用户！");
        }
        Dept dept = deptMapper.selectById(deptId);

        //根据like查询删除所有级联的城市合伙人
        QueryWrapper<Dept> wrapper = new QueryWrapper<>();
        wrapper = wrapper.like("PIDS", "%[" + dept.getDeptId() + "]%");
        List<Dept> subDepts = deptMapper.selectList(wrapper);
        for (Dept temp : subDepts) {
            this.removeById(temp.getDeptId());
        }

        this.removeById(dept.getDeptId());
    }

    /**
     * 获取ztree的节点列表
     *
     * @author fengshuonan
     * @Date 2018/12/23 5:16 PM
     */
    public List<ZTreeNode> tree() {
        return this.baseMapper.tree();
    }

    /**
     * 获取ztree的节点列表
     *
     * @author fengshuonan
     * @Date 2018/12/23 5:16 PM
     */
    public List<TreeviewNode> treeviewNodes() {
        return this.baseMapper.treeviewNodes();
    }

    /**
     * 获取所有城市合伙人列表
     *
     * @author fengshuonan
     * @Date 2018/12/23 5:16 PM
     */
    public Page<Map<String, Object>> list(String condition, String deptId) {
        Page page = LayuiPageFactory.defaultPage();
        return this.baseMapper.list(page, condition, deptId);
    }

    /**
     * 设置城市合伙人的父级ids
     *
     * @author fengshuonan
     * @Date 2018/12/23 4:58 PM
     */
    private void deptSetPids(Dept dept) {
        if (ToolUtil.isEmpty(dept.getPid()) || dept.getPid().equals(0L)) {
            dept.setPid(0L);
            dept.setPids("[0],");
        } else {
            Long pid = dept.getPid();
            Dept temp = this.getById(pid);
            String pids = temp.getPids();
            dept.setPid(pid);
            dept.setPids(pids + "[" + pid + "],");
        }
    }

    /**
     * 获取所有下级城市合伙人列表
     */
    public List<Dept> childDept(String name, Long deptId) {
        List<Dept> list = new ArrayList<>();
        ShiroUser user = ShiroKit.getUser();
        Long id = deptId;
        if (deptId == null) {
            assert user != null;
            id = user.getDeptId();
        }
        Dept dept = deptMapper.selectById(id);
        if (dept == null) {
            return list;
        }
        list.add(dept);
        List<Dept> childTree = createChildDept(id);
        if (!CollectionUtils.isEmpty(childTree)) {
            list.addAll(childTree);
        }
        if (!CollectionUtils.isEmpty(list)) {
            return list.stream()
                    .filter(o -> o.getSimpleName().contains(name))
                    .sorted(Comparator.comparing(Dept::getSort))
                    .collect(Collectors.toList());
        }
        return list;
    }

    private List<Dept> createChildDept(Long id) {
        List<Dept> list = new ArrayList<>();
        List<Dept> deptList = deptMapper.childDept(id);
        if (!CollectionUtils.isEmpty(deptList)) {
            for (Dept dept : deptList) {
                List<Dept> childTree = createChildDept(dept.getDeptId());
                if (childTree != null) {
                    list.addAll(childTree);
                }
            }
            list.addAll(deptList);
        } else {
            return null;
        }
        return list;

    }

    public List<ZTreeNode> childTree(String name) {
        ShiroUser user = ShiroKit.getUser();
        assert user != null;
        Long deptId = user.getDeptId();
        List<ZTreeNode> zTreeNodes = new ArrayList<>();
        Dept dept = deptMapper.selectById(deptId);
        if (dept != null) {
            zTreeNodes.add(createZtree(dept));
            List<ZTreeNode> childTree = createChildTree(dept.getDeptId());
            if (!CollectionUtils.isEmpty(childTree)) {
                zTreeNodes.addAll(childTree);
            }
            if (!StringUtils.isEmpty(name) && !CollectionUtils.isEmpty(zTreeNodes)) {
                return zTreeNodes.stream().filter(o -> o.getName().contains(name)).collect(Collectors.toList());
            }
        } else {
            ZTreeNode zNode = new ZTreeNode();
            zNode.setId(0L);
            zNode.setOpen(true);
            zNode.setChecked(false);
            zNode.setName("顶级");
            zTreeNodes.add(zNode);
        }
        return zTreeNodes;
    }

    private List<ZTreeNode> createChildTree(Long id) {
        List<ZTreeNode> list = new ArrayList<>();
        List<ZTreeNode> zTreeNodes = deptMapper.childTree(id);
        if (!CollectionUtils.isEmpty(zTreeNodes)) {
            for (ZTreeNode zTreeNode : zTreeNodes) {
                List<ZTreeNode> childTree = createChildTree(zTreeNode.getId());
                if (childTree != null) {
                    list.addAll(childTree);
                }
            }
            list.addAll(zTreeNodes);
        } else {
            return null;
        }
        return list;

    }

    private ZTreeNode createZtree(Dept dept) {
        ZTreeNode node = new ZTreeNode();
        node.setId(dept.getDeptId());
        node.setPId(0L);
        node.setName(dept.getSimpleName());
        node.setOpen(true);
        return node;
    }

}
